Grundfälle der ebenen Vektoralgebra

Oktober 2020
Keywords: Webkinematik, Webentwicklung, Getriebekinematik, Mechanismentechnik, Bewegungsübertragung, Kraftübertragung, Vektoralgebra, g2, mec2

6.1 Grundfall I

6.1.1 Aufgabenstellung

Analysieren Sie den dargestellten Mechanismus und stellen Sie diesen anschließend interaktiv mit der g2-Bibliothek im Browser dar.

Geg.: h=150 mm\quad h = 150\ mm, l=280 mml = 280\ mm, s={> 220 mm<200 mms=\left\{\begin{array}{ll} > -\ 220\ mm\\ < \quad 200\ mm \end{array}\right.



6.1.2 Kinematisches Modell

{ "gravity":true, "nodes": [ { "id":"A","x":0,"y":0 }, { "id":"A0","x":-220,"y":0,"base":true }, { "id":"B","x":0,"y":150,"base":true,"idloc":"e" }, { "id":"C","x":0,"y":280,"idloc":"ne" } ], "constraints": [ { "id":"b","p1":"B","p2":"A","len":{"type":"free"},"ori":{ "type":"drive","Dt":5,"Dw": -0.9732,"bounce":true,"func": "seq", "args": [ { "func": "linear", "dt": 2, "dz": 1 }, { "func": "const", "dt": 1 }, { "func": "linear", "dt": 2, "dz": 1 }] } }, { "id":"c","p1":"A","p2":"C","len":{"type":"const"},"ori":{ "type":"const","ref":"b" } }, { "id":"a","p1":"A0","p2":"A","len":{"type":"free"},"ori":{ "type":"const" },"lw":1, "ls":"black","ld":[20,4,2,4] } ], "shapes": [ { "type":"fix","p":"B" }, { "type":"flt","p":"A" }, { "type":"bar","p1":"A","p2":"C" }, { "type":"slider","p":"B","wref":"c"} ] }

Modell 1: Kinematisches Modell

6.1.3 Lösung

Zur interaktiven Darstellung im Canvas-Element werden die Koordinaten der Gliedpunkt AA, BB und CC in Abhängigkeit der Laufvariable ss des gegebenen Mechanismus benötigt.

Wir beginnen mit dem Aufstellen der Maschengleichung und identifizieren bzw. unterstreichen die unbekannten Größen. Anschließend wird die Gleichung derart umgeformt, sodass alle bekannten Variablen sich auf der rechten Seite befinden.

sex+beψhey=0beψ=heysexbeψ=g\begin{aligned} s\,\bm{e_x} + \underline{b}\,\underline{\bm{e_\psi}} - h\,\bm{e_y} &= 0\\ b\,\bm{e_\psi} &= h\,\bm{e_y} - s\,\bm{e_x}\\ b\,\bm{e_\psi}&= \bm{g}\end{aligned}

mit

g=heysex=(sh)\bm{g} = h\,\bm{e_y}-s\,\bm{e_x} = \begin{pmatrix}-\,s\\\quad h\end{pmatrix}

Da es einen unbekannten Vektor mit zugehörigem unbekanntem Skalar gibt, identifizieren wir Grundfall I.

Grundfall I

aeαbeβ=c\underline{a\,\bm{e_\alpha}}-b\,\bm{e_\beta}= \bm{c}

Lösung

a=(b+c)e~αundeα=b+caa = (\bm{b} + \bm{c})\,\bm{\tilde{e}_\alpha}\quad und\quad \bm{e_\alpha = \frac{\bm{b}+\bm{c}}{a}}

Die Länge bb lässt sich mit Satz des Pythagoras bestimmen.

b=h2+s2b = \sqrt{h^2+s^2}

Nun kann die allgemeine Lösung des 1. Grundfalles zur Bestimmung des vorliegenden Mechanismus verwerdet werden. Für eine strukturierte Vorgehensweise eignet sich das Anlegen einer Tabelle.

Grundfall I Mechanismus
aa bb
eα\bm{e_\alpha} eψ\bm{e_\psi}
beβb\,\bm{e_\beta} 00

Daraus resultiert

eψ=gb=1b(sh)\bm{e_\psi} = \frac{\bm{g}}{b} = \frac{1}{b}\begin{pmatrix}-\,s\\\quad h\end{pmatrix}

und

ψ=arctan2(hb,sb).\psi = \arctan_2\left(\frac{h}{b}, \frac{-s}{b}\right).

Die Umsetzung in HTML und JavaScript erfolgt entsprechend der Kapitel Animation und interaktive Elemente.

Als erstes wird ein Canvas-Element der Größe 500x400px, sowie ein Range-Input mit einem Bereich entsprechend der Vorgabe von s={> 220 mm<200 mms=\left\{\begin{array}{ll} > -\ 220\ mm\\ < \quad 200\ mm \end{array}\right., angelegt. Die Laufvariable ss wird als globale Variable angelegt. Zusätzlich wird ein mec-Objekt erstellt, das mittels number- & getter-Properties alle notwendigen Berechnungen vornimmt.

Nachdem die zu Beginn erarbeiteten mathematischen Erkenntnisse in Code überführt wurden, sollte das mec-Objekt folgendermaßen aussehen:

mec = { h: 150, l: 280, get g() { return {x:-s, y:h}; }, get b() { return Math.sqrt(this.h*this.h + s*s); }, get psi() { return Math.atan2(this.h/this.b, -s/this.b); }, get epsi() { return {x:Math.cos(this.psi), y:Math.sin(this.psi)}; }, // Gelenkpunkte get A() { return {x:+s, y:0}; }, get B() { return { x:0, y:this.h }; }, get C() { return { x:this.A.x + this.l*this.epsi.x, y:this.A.y + this.l*this.epsi.y }; } }

Den Mechanismus und die zugegebenermaßen bei diesem Beispiel kaum vorhandene statische Umgebung, teilen wir wie gehabt in ein statisches (world)

// baut und initialisiert die statische Umgebung world = g2().clr() .view({cartesian:true,x:250,y:100}) // Nullpunkt verschoben .use({grp:g}) .nodfix({...mec.B}),

und dynamisches (g) g2-Objekt auf, das wir in der postion()-Funktion füllen.

const g = g2(); //... function position() { g.del() .bar({x1:mec.A.x, y1:mec.A.y, x2:mec.C.x, y2:mec.C.y}) .slider({...mec.B, w:mec.psi, fs:"@nodfill"}) .nodflt({...mec.A}) .nod({...mec.C}) }

Die Aktualisierung der Laufvariable, die Implementierung des dirty-flags, die Erstellung der render()-Funktion sowie des restlichen Quellcodes verhalten sich vollständig analog zu den Beispielen aus den vorherigen Kapiteln.

Der fertige Quelltext sollte folgendermaßen aussehen

<!doctype html> <html> <head> <meta charset='utf-8'> <title>Schubschleife</title> </head> <body> <h2>Schubschleife - Grundfall 1</h2> <canvas id="c" width="500" height="400" style="border-width:1px;border-style:solid"></canvas> <br> <label for="sslider">s: <input type="range" id="sslider" style="width:450px;vertical-align:middle;padding:0" min="-200" max="200" value="0"> <output id="sout" for="sslider">0</output>mm </label> <script src="https://gitcdn.xyz/repo/goessner/g2/master/src/g2.js"></script> <script> const cnv = document.getElementById('c'), ctx = cnv.getContext('2d'), sslider = document.getElementById('sslider'), sout = document.getElementById('sout'), mec = { h: 150, l: 280, get g() { return {x:-s, y:h}; }, get b() { return Math.sqrt(this.h*this.h + s*s); }, get psi() { return Math.atan2(this.h/this.b, -s/this.b); }, get epsi() { return {x:Math.cos(this.psi), y:Math.sin(this.psi)}; }, // Gelenkpunkte get A() { return { x:s, y:0}; }, get B() { return { x:0, y:this.h }; }, get C() { return { x:this.A.x + this.l*this.epsi.x, y:this.A.y + this.l*this.epsi.y }; } }, g = g2(), // baut und initialisiert statische Umgebung world = g2().clr() .view({cartesian:true,x:250,y:100}) // Nullpunkt verschoben .use({grp:g}) .nodfix({...mec.B}); let s = 0, // Laufvariable dirty = true; // wenn true gibt es was zu aktualisieren function position() { g.del() .bar({x1:mec.A.x,y1:mec.A.y,x2:mec.C.x,y2:mec.C.y}) .slider({...mec.B, w:mec.psi}) .nodflt({...mec.A}) .nod({...mec.C}) } function render() { if (dirty) { position(); // aktualisiere Position world.exe(ctx); // rendert world in den Context dirty = false; } requestAnimationFrame(render); // asynchroner callback von render(), keine Rekursion! } function sets() { if (sslider.value != sout.value) { s = +sslider.value; sout.innerHTML = sslider.value; dirty = true; } } /* * Initialisierung */ // Eventlistener hinzufuegen sslider.addEventListener("input",sets); // Animation starten render(); </script> </body> </html>